/*
 * File:    AutoBuffer.java
 * Created: 31-Oct-2007
 *
 * by Kenji Hollis <kenji@bitgatesoftware.com>
 * Released under the Creative Commons License version 2.5
 */

package com.bitgate.util.buffer;

/**
 * This class automatically creates a memory-based buffer for you, and allows the system to automatically handle the
 * transition of the buffer from memory to disk state, and vice versa.  It allows you to set a maximum size before the
 * memory buffer gets persisted to disk, and allows for hooks to verify whether or not data has been persisted to
 * disk.
 * <p></p>
 * This is strictly a helper buffer class, and does not know about any of the other types of classes yet.  There may
 * be a Spring configuration at some point that will allow you to change the memory/disk persist objects that are used.
 * For now, these are non-configurable.
 * 
 * @author kenji
 * @since 0.1
 */
public class AutoBuffer {
	
	public static final long DEFAULT_AUTOPERSIST_SIZE = 65536L;
	
	private BufferInterface currentBuffer;
	private long autoPersistSizeBounds;
	
	/**
	 * Constructor.
	 * 
	 * @throws BufferException on any errors.
	 */
	public AutoBuffer() throws BufferException {
		this.currentBuffer = BufferFactory.getInstance().get("memory");
		this.autoPersistSizeBounds = DEFAULT_AUTOPERSIST_SIZE;
	}
	
	/**
	 * Sets the persistence size boundary.  If this persistence size is exceeded, the system automatically
	 * persists the data to the disk.  Once the persistence size bounds is not exceeded, the buffer
	 * automatically loads the data from disk into memory, and flushes the cache from disk.
	 * 
	 * @param sizeBounds <code>long</code> containing the size of the buffer.
	 * @throws BufferException on any errors.
	 */
	public void setPersistSizeBounds(long sizeBounds) throws BufferException {
		autoPersistSizeBounds = sizeBounds;
		checkBuffer();
	}
	
	/**
	 * Indicates whether or not the buffer has been persisted to disk.
	 * 
	 * @return <code>true</code> if the buffer has been persisted, <code>false</code> otherwise.
	 */
	public boolean isDiskPersisted() {
		return (currentBuffer instanceof AbstractDiskBuffer);
	}
	
	/**
	 * Forces persistence to disk.
	 * 
	 * @throws BufferException on any errors.
	 */
	public void persistToDisk() throws BufferException {
		currentBuffer = currentBuffer.persistToStorage();
	}
	
	/**
	 * Returns the <code>BufferInterface</code> object.
	 * 
	 * @return <code>BufferInterface</code> object.
	 */
	public BufferInterface getBuffer() {
		return currentBuffer;
	}
	
	/**
	 * internal consistency check to see if the size is larger than the auto-persistence bounds.
	 * 
	 * @throws BufferException on any errors.
	 */
	private void checkBuffer() throws BufferException {
		if (currentBuffer.size() > autoPersistSizeBounds) {
			persistToDisk();
		}
	}
	
}